package com.thx.org.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import com.thx.common.spring.BeanFactory;
import com.thx.org.Org;
import com.thx.org.OrgChangeListener;
import com.thx.org.OrgManager;
import com.thx.org.model.Department;

/**
 * @author balance
 * 
 */
public class OrgManagerImpl implements OrgManager {

	private DepartmentManager depMgr;

	private CompanyManager comMgr;

	private static HashMap<Class, OrgChangeListener> listeners;

	private static OrgManager orgMgr;

	public final int EVENT_SAVE = 1;
	public final int EVENT_UPDATE = 2;
	public final int EVENT_DELETE = 3;

	private OrgManagerImpl() {
		depMgr = (DepartmentManager) BeanFactory.getBean(DepartmentManager.class);
		comMgr = (CompanyManager) BeanFactory.getBean(CompanyManager.class);

		depMgr.setOrgMgr(this);
		comMgr.setOrgMgr(this);

	}

	public static OrgManager getInstance() {
		if (orgMgr == null) {
			synchronized (OrgManagerImpl.class) {

				if (orgMgr == null)
					orgMgr = new OrgManagerImpl();
			}
		}
		return orgMgr;
	}

	@Override
	public List<? extends Org> getChildren(String orgId) {
		return getChildrenRecursive(orgId);
	}

	private List<Department> getChildrenRecursive(String orgId) {
		List<Department> children = depMgr.getByParentId(orgId);
		if (children != null && children.size() > 0) {
			for (Department dep : children) {
				dep.setChildren(getChildrenRecursive(dep.getDepId()));
			}
		}
		return children;
	}

	public Org getRoot() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void addListener(OrgChangeListener listener) {
		if (listener == null)
			return;
		synchronized (this) {
			if (listeners == null)
				listeners = new HashMap<Class, OrgChangeListener>();

			if (!listeners.containsKey(listener.getClass()))
				listeners.put(listener.getClass(), listener);
		}
	}

	@Override
	public void removeListener(OrgChangeListener listener) {
		if (listener == null || listeners == null)
			return;
		synchronized (this) {
			listeners.remove(listener.getClass());
		}
	}

	public boolean notify(int EvenType, Org org) {

		boolean ok = true;

		if (listeners != null && listeners.size() > 0) {
			Set<Entry<Class, OrgChangeListener>> set = listeners.entrySet();

			switch (EvenType) {
			case EVENT_SAVE:
				for (Entry<Class, OrgChangeListener> entry : set) {
					OrgChangeListener listener = entry.getValue();
					ok = ok && listener.onAdd(org);
				}
				break;
			case EVENT_UPDATE:
				for (Entry<Class, OrgChangeListener> entry : set) {
					OrgChangeListener listener = entry.getValue();
					ok = ok && listener.onUpdate(org);
				}
				break;
			case EVENT_DELETE:
				for (Entry<Class, OrgChangeListener> entry : set) {
					OrgChangeListener listener = entry.getValue();
					ok = ok && listener.onDelete(org);
				}
			}
		}

		return ok;
	}
}
